/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "socket_utils.h"


#include "插座/通用插座.h"
#include "插座/C_数值插座.h"
#include "插座/C_单值矢量插座.h"
#include "插座/C_物体插座.h"
#include "插座/C_物理物体插座.h"
#include "插座/材质纹理插座.h"
#include "插座/几何插座.h"

#include "插座/list/list矢量插座.h"
#include "插座/list/list数值插座.h"
#include "插座/list/list物理物体插座.h"
#include "插座/list/list物体插座.h"
#include "插座/list/list元素插座.h"

//#include "../节点/包节点.h"

using namespace std;





C_插座基类* f_su_创建节点后端插座(const wstring& socketName, E_值类型 type, void* mapdata, S_设备环境* ctx) {
	C_插座基类* socket = 0;

	switch (type) {
	//case e_插座Type_None:
	case e_Type_Bool:
		socket = new C_插座基类(socketName);
		break;
	case e_Type_LineText:
		break;
	case e_Type_F32:
		socket = new C_F32插座(socketName, (float32*)mapdata);
		break;
	case e_Type_F64:
		socket = new C_F64插座(socketName, (float64*)mapdata);
		break;
	case e_Type_I8: socket = new C_I8插座(socketName);
		break;
	case e_Type_I16:
		socket = new C_I32插座(socketName, (int32*)mapdata);
	case e_Type_I32:
		socket = new C_I32插座(socketName, (int32*)mapdata);
		break;
	case e_Type_UI32:
		socket = new C_UI32插座(socketName);
		break;
	case e_Type_I64: socket = new C_UI64插座(socketName);
		break;
	case e_Type_UI64: socket = new C_UI64插座(socketName);
		break;
	case e_Type_Vec2: socket = new C_Vec2插座(socketName);
		break;
	case e_Type_Vec3: socket = new C_Vec3插座(socketName);
		break;
	case e_Type_Vec4: socket = new C_Vec4插座(socketName);
		break;
	case e_Type_iVec2: socket = new C_iVec2插座(socketName);
		break;
	case e_Type_iVec3: socket = new C_iVec3插座(socketName);
		break;
	case e_Type_Shader: socket = new C_着色器插座(socketName);
		break;
	case e_Type_uVec2: socket = new C_uVec2插座(socketName);
		break;
	case e_Type_uVec3: socket = new C_uVec3插座(socketName);
		break;
	case e_Type_uVec4: socket = new C_uVec4插座(socketName);
		break;
	case e_Type_Mat2X2:
		break;
	case e_Type_Mat3X3: socket = new C_Mat3X3插座(socketName);
		break;
	case e_Type_Mat4X4: socket = new C_Matrix4X4插座(socketName);
		break;
	case e_Type_Object:
		socket = new C_物体插座(socketName);
		break;
	case e_Type_Mesh:
		socket = new C_网格插座(socketName);
		break;
	case e_Type_Mesh_1D:
		socket = new C_网格1D插座(socketName);
		break;
	//case e_插座Type_BlMesh:
	//	break;
	case e_插座Type_Line:
		break;
	case e_插座Type_Line_Array1D:
		socket = new C_线段插座_Array1D(socketName);
		break;

	case E_值类型::e_Type_多边形面: socket = new C_多边形面插座(socketName); break;
	//case E_值类型::e_Type_多边形面1D: socket = new C_多边形面插座_1D(socketName); break;

	case E_值类型::e_Type_多边形: socket = new C_多边形插座(socketName); break;
	case E_值类型::e_Type_多边形_1D: socket = new C_多边形插座_1D(socketName); break;

	case e_Type_骨骼:
		socket = new C_骨骼插座(socketName);
		break;

	//case e_插座Type_Particles:
	//	break;
	case e_Type_Scene:
		//socket = new C_场景插座(socketName);
		break;
	case e_Type_集合:
		//socket = new C_集合插座(socketName);
		break;
	case e_Type_面顶点索引:
		//socket = new C_面顶点索引插座(socketName);
		break;
	case e_Type_多边形边:
		socket = new C_多边形边插座(socketName);
		break;
	case e_Type_多边形边1D:
		socket = new C_多边形边_1D插座(socketName);
		break;
	case e_Type_多边形元素:
		socket = new C_多边形元素插座(socketName);
		break;
	case e_Type_多边形元素1D:
		socket = new C_多边形元素_1D插座(socketName);
		break;
	case e_Type_车轮:
		//socket = new C_车轮属性插座(socketName);
		break;
	case e_Type_车辆:
		//socket = new C_车辆属性插座(socketName);
		break;
	//case e_插座Type_物理体:
	//	socket = new C_物理体插座(socketName);
	//	break;
	case e_插座Type_物理体_Array1D:
		socket = new C_插座_物理体Array1D(socketName);
		break;
	case e_插座Type_物理平面:
		break;
	
	case e_插座Type_引用数据:
		socket = new C_引用数据插座(socketName);
		break;


	case E_值类型::e_Type_Bool_1D:
		socket = new C_插座Bool_1D(socketName);
		break;

	case e_Type_F32_Array1D:
		socket = new C_Vector1D_F32插座(socketName);
		break;
	case e_Type_F32_1D: socket = new C_F32_1D插座(socketName);
		break;
	case e_Type_I8_1D: socket = new C_插座I8_Array1D(socketName);
		break;
	case e_Type_I32_1D:
		socket = new C_插座I32_1D(socketName);
		break;
	case e_插座Type_I32_Array2D:
		//socket = new C_插座I32_Array2D(socketName);
		break;
	case e_Type_UI32_1D: socket = new C_UI32插座_Array1D(socketName); break;
	case e_Type_UI32_2D: socket = new C_UI32_2D插座(socketName); break;
	case e_插座Type_UI32_Array2D:
		//socket = new C_UI32插座_Array1D(socketName);
		break;
	case e_Type_I64_Array1D:
		break;

	case e_Type_Vec2_Array1D: socket = new C_Vector1D_Vec2插座(socketName);
		break;
	case e_Type_Vec3_Array1D: socket = new C_Vector1D_Vec3插座(socketName);
		break;
	case e_Type_Vec2_1D: socket = new C_Vec2_1D插座(socketName);
		break;

	case e_Type_Vec3_1D: socket = new C_Vec3_1D插座(socketName); break;
	case e_Type_Vec3_2D: socket = new C_Vec3_2D插座(socketName); break;

	case e_Type_Vec4_1D: socket = new C_Vec4_1D插座(socketName);
		break;

	case e_Type_iVec3_1D: socket = new C_iVec3_1D插座(socketName); break;
	case e_Type_iVec3_2D: socket = new C_iVec3_2D插座(socketName); break;

	case e_Type_纹理: socket = new C_纹理插座(socketName, *ctx); break;
	case e_Type_纹理1D: socket = new C_纹理1D插座(socketName); break;

	case e_Type_iVec2_1D: socket = new C_iVec2_1D插座(socketName);
		break;
	case e_Type_uVec2_1D: socket = new C_uVec2_1D插座(socketName);
		break;
	case e_Type_Array: socket = new C_数组插座(socketName);
		break;
	case e_插座Type_Mat2X2_Array1D:
		break;
	case e_插座Type_Mat3X3_Array1D:
		break;
	case e_Type_Mat4X4_Array1D:
		socket = new C_Array1D_Mat4X4插座(socketName);
		break;
	case e_Type_Mat4X4_1D: socket = new C_Mat4X4_1D插座(socketName); break;

	case E_值类型::e_插座Type_Vec球:
		//socket = new C_Vec球插座(socketName);
		break;
	case E_值类型::e_Type_VecSphere_1D:
		socket = new C_Vec球_1D_插座(socketName);
		break;


	case e_Type_Object_Array1D:
		socket = new C_插座_物体Array1D(socketName);
		break;
	case e_Type_Object_1D:
		socket = new C_物体插座_1D(socketName);
		break;

	case e_Type_材质: socket = new C_材质插座(socketName); break;

	case e_Type_材质1D: socket = new C_材质_1D插座(socketName); break;
	
	//case e_插座Type_VectorLine:
	//	break;
	case e_插座Type_VectorParticle:
		break;
	case e_插座Type_VectorScene:
		break;
	case e_插座Type_物理材质_Array1D:
		//socket = new C_插座_物理材质Array1D(socketName);
		break;
	case e_插座Type_物理几何_Array1D:
		//socket = new C_插座_物理几何Array1D(socketName);
		break;
	case e_插座Type_车轮_Array1D:
		break;
	case e_插座Type_车辆_Array1D:
		break;
	case e_插座Type_物理平面_Array1D:
		break;
	case e_插座Type_通用取:
		break;
	
	default:
		break;
	}


	if (!socket) {
		cout << "施工中" << endl;
	}

	return socket;
}

C_插座基类* f_su_切换后端插座类型(C_节点基类* node, E_插座方向 dir, int16 oldSocketLoc, E_值类型 newType, void* mapdata) {
	C_插座基类* socket = 0;
	C_插座基类* linkSocket = 0;
	if (dir == E_插座方向::e_插座Type_输出) {
		socket = node->f_get输出插座(oldSocketLoc);
	}
	else {
		socket = node->f_get输入插座(oldSocketLoc);
	}
	if (socket->m_Type == newType) return socket;

	C_插座基类* newSocket = f_su_创建节点后端插座(socket->m_identifier, newType, mapdata, &node->m_Ctx);
	
	if (newSocket) {
		newSocket->f_set回写(socket->f_is回写());
		node->f_替换插座(newSocket, oldSocketLoc, dir);
	}
	return newSocket;
}


void f_su_重构插座(E_插座方向 方向, C_节点基类* node, std::vector<S_类型名称>& socketType, void* mapdata) {
	uint32 多余插座数量 = 0;
	uint32 newNum = socketType.size();

	uint32 num;
	if (方向 == E_插座方向::e_插座Type_输入) {
		num = node->f_get输入插座Num() - 1;
	}
	else {
		num = node->f_get输出插座Num() - 1;
	}

	for (uint32 i = 0; i < newNum; ++i) {
		if (i < num) {
			auto* socket = f_su_切换后端插座类型(node, 方向, i+1, socketType[i].type, mapdata);
			//if (socket->on_UI更新) socket->on_UI更新(socket);
		}
		else {
			auto socket = f_su_创建节点后端插座(socketType[i].name, socketType[i].type, mapdata, &node->m_Ctx);
			node->f_add插座(socket, 方向);
		}
	}

	if (num > newNum) {
		num -= newNum;
		for (uint32 i = 0; i < num; ++i) {
			uint32 index = node->f_get输入插座Num() - 1;
			node->f_del插座(index, 方向);
		}
	}
}

void f_su_插座类型切换到连入的插座类型(C_节点基类* node, E_插座方向 dir, int16 oldSocketLoc, E_值类型 默认类型) {
	switch (dir) {
	case E_插座方向::e_插座Type_输入: {
		auto* socket = node->f_get输入插座(oldSocketLoc);
		C_插座基类* 链接到的插座 = socket->f_getLinkOutSocket();
		if (链接到的插座) {
			f_su_切换后端插座类型(node, dir, oldSocketLoc, 链接到的插座->m_Type);
		}
		else {
			f_su_切换后端插座类型(node, dir, oldSocketLoc, 默认类型);
		}
		break;
	}
	case E_插座方向::e_插座Type_输出: {
		auto* socket = node->f_get输出插座(oldSocketLoc);
		auto 链接到的插座 = socket->f_get链接到的输入插座();
		if (链接到的插座.size()) {
			f_su_切换后端插座类型(node, dir, oldSocketLoc, 链接到的插座.front()->m_Type);
		}
		break;
	}
	}
}

void f_su_拷贝插座(C_节点基类* 源节点, C_节点基类* 目标节点, E_插座方向 源插座方向, E_插座方向 目标插座方向) {
	uint32 socketNum = 0;
	if (源插座方向 == E_插座方向::e_插座Type_输入) {
		socketNum = 源节点->f_get输入插座Num();

		for (uint32 j = 0; j < socketNum; ++j) {
			auto* p_socket = 源节点->f_get输入插座(j);
			if (j >= 目标节点->f_get输入插座Num()) {
				目标节点->f_add插座(f_su_创建节点后端插座(p_socket->m_identifier, p_socket->m_Type, nullptr, &目标节点->m_Ctx), 目标插座方向);
			}
			else {
				auto socket = f_su_切换后端插座类型(目标节点, 目标插座方向, j, p_socket->m_Type);
				socket->m_identifier = p_socket->m_identifier;
			}
		}
	}
	else {
		socketNum = 源节点->f_get输出插座Num();

		for (uint32 j = 0; j < socketNum; ++j) {
			auto* p_socket = 源节点->f_get输出插座(j);
			if (j >= 目标节点->f_get输出插座Num()) {
				目标节点->f_add插座(f_su_创建节点后端插座(p_socket->m_identifier, p_socket->m_Type, nullptr, &目标节点->m_Ctx), 目标插座方向);
			}
			else {
				auto socket = f_su_切换后端插座类型(目标节点, 目标插座方向, j, p_socket->m_Type);
				socket->m_identifier = p_socket->m_identifier;
			}
		}
	}
}

void f_su_数据拷贝到GPU(C_插座基类* socket)	{
	switch (socket->m_Type) {
		case E_值类型::e_Type_Vec2:
			f_buf_Vec2_at(socket->m_GPU缓存) = DEF_Vec2插座数据(socket);
			break;
		case E_值类型::e_Type_uVec2:
			f_buf_uVec2_at(socket->m_GPU缓存) = DEF_uVec2插座数据(socket);
			break;
		default:
			break;
	}
}




